



/*
App Key：1770208665
App Secret：ee95093ff52e9f3659018e6bb84d4d77

redirect_uri :http://www.baidu.com

https://api.weibo.com/oauth2/authorize

https://api.weibo.com/oauth2/authorize?client_id=1770208665&redirect_uri=http://www.baidu.com


App Key：100322432
App Secret：bcbf340e112a0218e202bbd3fd800eb7
http://www.baidu.com

拼接的整个路径 获取 token 值
https://api.weibo.com/oauth2/authorize?client_id=100322432&redirect_uri=http://www.baidu.com

//测试网站
//    "https://api.weibo.com/oauth2/authorize?client_id=1770208665&redirect_uri=http://www.baidu.com"

//        请求方式：get
//        请求URL：https://api.weibo.com/2/users/show.json
//        请求参数：uid=2127758760&access_token=2.00gPrz_C0k8wmGa1c7576f76pN7TWD

*/

import UIKit

import AFNetworking
import ReactiveCocoa

// swift中枚举的变化非常大，可以有构造函数，可以有静态函数，可以有函数，可以遵守协议
enum ResquestMethod:String{
    case GET = "GET"
    case POST = "POST"
}
class NetworkTools: AFHTTPSessionManager {

    //单例
    static let sharedTools:NetworkTools = {
        //指定 baseURL
        var instance = NetworkTools(baseURL: nil)
        instance.responseSerializer.acceptableContentTypes?.insert("text/plain")
        return instance
        }()
    
    let clientId = "1770208665"
    let clientSecret = "ee95093ff52e9f3659018e6bb84d4d77"
    let redirectUri = "http://www.baidu.com"
    
    /// -see:[https://api.weibo.com/oauth2/authorize](https://api.weibo.com/oauth2/authorize)
    var oauthUrl:NSURL{
        let urlString = "https://api.weibo.com/oauth2/authorize?client_id=\(clientId)&redirect_uri=\(redirectUri)"
        return NSURL(string: urlString)!
    }
    
    ///  发送微博
    ///
    ///  - parameter status: 微博内容
    ///  - parameter  status	true	string	要发布的微博文本内容，必须做URLencode，内容不超过140个汉字。
    ///  - returns: RACSignal
    ///  - see:[http://open.weibo.com/wiki/2/statuses/update](http://open.weibo.com/wiki/2/statuses/update)
    func sendStatus(status:String,image:UIImage?) ->RACSignal{
    
        let params = ["status":status]
        
        if image == nil{
            return request(.POST, URLString: "https://api.weibo.com/2/statuses/update.json", parameters: params)
        }else{
        
            return upload("https://upload.api.weibo.com/2/statuses/upload.json", parameters: params, image: image!)
        }
    }
    
    
    //MARK: - 微博数据
    ///  加载微博数据
    //since_id	false	:若指定此参数，则返回ID比since_id大的微博（即比since_id时间晚的微博），默认为0。
    //max_id	false	:若指定此参数，则返回ID小于或等于max_id的微博，默认为0。
    ///
    ///  - returns: RAC Sianal 
    /// - see: [http://open.weibo.com/wiki/2/statuses/home_timeline](http://open.weibo.com/wiki/2/statuses/home_timeline)
    func loadStatus(since_id since_id:Int,max_id:Int) ->RACSignal{
    
        let urlString = "https://api.weibo.com/2/statuses/home_timeline.json"
        
        // 创建空的参数字典
        var params = [String:AnyObject]()
        if since_id > 0{
            params["since_id"] = since_id
        }else if max_id > 0{
            params["max_id"] = max_id - 1
        }
        
        return request(.GET, URLString: urlString, parameters: params)
    }
    
    
    
    ///获取AcceccToken
    ///- parameter code:       请求码/授权码
    /// - see:[http://open.weibo.com/wiki/OAuth2/access_token](http://open.weibo.com/wiki/OAuth2/access_token)
    func loadAccessToken(code:String) ->RACSignal{
        
        //需要什么信息，怎么样获取信息
        let urlString = "https://api.weibo.com/oauth2/access_token"
        let params = ["client_id":clientId,"client_secret":clientSecret,"grant_type":"authorization_code","code":code,"redirect_uri":redirectUri]
    
        return request(.POST, URLString: urlString, parameters: params ,withToken:false)

    }
    
    ///  加载用户信息
    ///  - parameter uid:          uid
    ///  - parameter access_token: access_token
    ///
    ///  - returns: RAC Sianal
    /// - see:[https://api.weibo.com/2/users/show](https://api.weibo.com/2/users/show)
    func loadUserInfo(uid:String) ->RACSignal{
        
        let urlString = "https://api.weibo.com/2/users/show.json"
        let params = ["uid":uid]
        
        return request(.GET, URLString: urlString, parameters: params)
        
    }
    
    
    private func appenToken(inout parameters:[String:AnyObject]?) ->Bool{
        //判断单例中的token 是否有效
        guard let token = UserAccountViewModel.sharedUserAccount.accessToken else{
        
            return false
        }
        
        //判断是否传递了 参数字典
        if parameters == nil{
            parameters = [String:AnyObject]()
        }
        //后续的 token  都是有效的
        parameters!["access_token"] = token
        return true
    }

    
    ///  网络请求方法 （对方法的 GET & POST 进行了封装 ）
    ///
    ///  - parameter method:     method
    ///  - parameter URLString:  URLString
    ///  - parameter parameters: 参数字典
    ///
    ///  - returns: RAC Signal
    ///封装AFN网络请求，网络请求的核心框架都封装在这个方法里
    func request(method:ResquestMethod ,URLString:String,var parameters:[String:AnyObject]?,withToken:Bool = true) ->RACSignal{
        
        return RACSignal.createSignal({ (subscriber) -> RACDisposable! in
            
            // 0. 判断是否需要 token
            if withToken && !self.appenToken(&parameters){
                subscriber.sendError(NSError(domain: "com.fanglanfeng", code: -10001, userInfo: ["errorMessage":"Token 为空"]))
                return nil
            }
            
            //1.成功的回调闭包
            let successCallBack = {(task:NSURLSessionDataTask, result:AnyObject) -> Void in
                //将结果发送给订阅者
                subscriber.sendNext(result)
                //完成
                subscriber.sendCompleted()
            }
            //2.失败的回到信息
            let failureCallBack = { (task:NSURLSessionDataTask, error:NSError) -> Void in
                print(error)
                subscriber.sendError(error)
            }
            
            //3. 根据方法，选择不同的网络方法
            if method == ResquestMethod.GET{
                self.GET(URLString, parameters: parameters, success: successCallBack, failure: failureCallBack)
            }else{
                
                self.POST(URLString, parameters: parameters, success: successCallBack, failure: failureCallBack)
            }
            return nil
        })
    }
    
    
    ///  上传文件
    ///
    ///  - parameter URLString:  URLString
    ///  - parameter parameters: parameters
    ///  - parameter image:      image
    ///
    ///  - returns: RAC Signal
    private func upload(URLString:String,var parameters:[String:AnyObject]?,image:UIImage) ->RACSignal {
    
        //闭包返回值是对限号销毁时需要做的内存销毁工作，同样的一个 block ,AFN 的可以直接nil
        return RACSignal.createSignal(){ (subscriber) -> RACDisposable! in
            
            // 0. 判断是否需要 token
            if !self.appenToken(&parameters){
                subscriber.sendError(NSError(domain: "com.fanglanfeng", code: -10001, userInfo: ["errorMessage":"Token 为空"]))
                return nil
            }
            //1.调用AFN的上传方法
            self.POST(URLString, parameters: parameters, constructingBodyWithBlock: { (formData) -> Void in
                
                /** formData 是遵守协议的对象，AFN 内部提供的，使用的时候，只需要按照协议方法传递参数即可
                
                1.要上传图片的二进制数据
                2.服务器的字段名，开发的时候，咨询后台
                3.保存在服务器的文件名，很多后台允许随便写
                4.mimeType  --> 客户端高速服务器上传文件的类型，格式
                大类/小类
                image/jpg
                image/gif
                image/png
                如果，不想高速服务器具体的类型，可以使用 application/octet-stream
                */
                //将图像转换成二进制数据
                
                let data = UIImagePNGRepresentation(image)!
                
                formData.appendPartWithFileData(data, name: "pic", fileName: "ohoh", mimeType: "application/octet-stream")
                
                }, success: { (_, result) -> Void in
                    
                    subscriber.sendNext(result)
                    subscriber.sendCompleted()
                }) { (_, error) -> Void in
                    
            }
            return nil
        }
        
        
    }

    
}



















